package mt.dummy;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import mt.Order;
import mt.comm.ClientComm;
import mt.comm.ClientSideMessage;
import mt.comm.ServerSideMessage;

/**
 * Communication class for MicroTrader clients.
 * MicroTrader clients must communicate with MicroTrader server
 * through this class.
 * @author Group45
 *
 */
public class ClientCommDummy implements ClientComm {
	private Socket socket = null;
	private String nickname;
	
	
	private static final int PORTO = 8080;
	private ObjectInputStream in;
	private ObjectOutputStream out;
	
	DealWithServer dealWithserver;
	Queue<ClientMessage> messages = new LinkedList<ClientMessage>();
	
	

	/**
	 * This method starts the connection between a client and the server. 
	 * And also creates a DealWithServer. 
	 * @param serverAddress the address of the server which the client will be connecting. 
	 * @param nickname the client nickname
	 */
	@Override
	public void connect(String serverAddress, String nickname) {
		
		try {
			InetAddress endereco = InetAddress.getByName(serverAddress);
			System.out.println("Endereco = " + endereco);
			socket = new Socket(endereco, PORTO);
			System.out.println("Socket = " + socket);
			dealWithserver = new DealWithServer(socket,this, this.nickname);
			dealWithserver.start();
			this.nickname=nickname;

		} catch (UnknownHostException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
		
	}

	/**
	 * Check if currently connected to a host.
	 * 
	 * @return <b>true</b> if currently connected to a host, <b>false</b> otherwise.
	 */
	@Override
	public boolean isConnected() {
		return !(socket.isClosed());
	}

	/**
	 * Disconnects from the server. Any sockets should be closed immediately. 
	 * Pending orders are not guaranteed to be delivered before disconnecting.
	 */	
	@Override
	public void disconnect() {

		ServerMessage serverMessage = new ServerMessage(ServerSideMessage.Type.DISCONNECTED,this.nickname);
		
		try {
			out.writeObject(serverMessage);
			socket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}
	

	@Override
	public ClientSideMessage getNextMessage() {

		if(!messages.isEmpty()){
			ClientSideMessage nextMessage = messages.remove();
			return nextMessage;
		}
		
		return null;
	}
	
	/** 
	 * Checks if a message from the server is pending. If {@link #hasNextMessage()} returns true, a call to {@link #getNextMessage} 
	 * will return immediately with the oldest message in the queue. If {@link #hasNextMessage()} returns false, a call to {@link #getNextMessage} 
	 * will block until a message has been received.
	 * 
	 * @return <b>true</b> if a message from the server is currently pending, otherwise <b>false</b>.
	 */
	@Override
	public boolean hasNextMessage() {
		// TODO Auto-generated method stub
		return !messages.isEmpty();
	}

	@Override
	public void sendOrder(Order order) {

		ServerMessage serverMessage = new ServerMessage(ServerSideMessage.Type.NEW_ORDER,this.nickname, order);
		
		try {
			out.writeObject(serverMessage);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * * Adds a message to a list.
	 *
	 * @param mensagem message to add
	 */
	public void addMessage(ClientMessage mensagem){
		messages.add(mensagem);
	}

}
